package nhentai

import (
	"context"
	"fmt"
	"golang.org/x/net/proxy"
	"io"
	"net/http"
	"os"
	"sync"
)

type nHentaiClient struct {
	Cfduid string
	Cli    http.Client
	Proxy  proxy.Dialer // 不为nil则走proxy
}

func (hcli nHentaiClient) Fetch(ctx context.Context, bookNum string, start, end int) {
	wg := sync.WaitGroup{}
	tasksDone := make(chan struct{})
	for i := start; i <= end; i++ {
		name := fmt.Sprintf("%d.jpg", i)
		wg.Add(1)
		go func(bookNum, imgName string) {
			defer wg.Done()
			err := hcli.FetchOne(bookNum, imgName)
			if err != nil {
				fmt.Printf("fetchOne(%s, %s): %s\n", bookNum, imgName, err.Error())
				return
			}
			fmt.Printf("%s finish!\n", name)
		}(bookNum, name)
	}
	go func() {
		wg.Wait()
		tasksDone <- struct{}{}
	}()
	select {
	case <-tasksDone:
	case <-ctx.Done():
		fmt.Println(ctx.Err())
	}
}

func (hcli nHentaiClient) FetchOne(bookNum, imgName string) error {
	u := fmt.Sprintf("https://i.nhentai.net/galleries/%s/%s", bookNum, imgName)
	cli := hcli.Cli
	if hcli.Proxy != nil {
		cli.Transport = hcli.socks5Transport()
	}
	req, _ := http.NewRequest("GET", u, nil)
	req.Header.Set("user-agent",
		"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36")
	req.Header.Set("__cfduid", hcli.Cfduid)
	resp, err := cli.Do(req)
	if err != nil {
		return err
	}
	_ = os.Mkdir(bookNum, os.ModePerm)
	f, err := os.Create(fmt.Sprintf("%s/%s-%s", bookNum, bookNum, imgName))
	if err != nil {
		return err
	}
	defer func() { _ = f.Close() }()
	if _, err = io.Copy(f, resp.Body); err != nil {
		return err
	}
	return nil
}

func (hcli nHentaiClient) socks5Transport() *http.Transport {
	httpTransport := &http.Transport{}
	httpTransport.Dial = hcli.Proxy.Dial
	return httpTransport
}

func defaultProxy() proxy.Dialer {
	d, err := proxy.SOCKS5("tcp", "127.0.0.1:1080", nil, proxy.Direct)
	if err != nil {
		panic(err)
	}
	return d
}
